package com.googlecode.imanager.client.style;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
// TODO usar um objeto color ao invés de Integer
public final class Color {

    public static final Color TRANSPARENT = Color.valueOf(0xffffffff, true);
    
    public static final Color WHITE = Color.valueOf(0xffffff);
    public static final Color RED = Color.valueOf(0xff0000);
    public static final Color GREEN = Color.valueOf(0x00ff00);
    public static final Color BLUE = Color.valueOf(0x0000ff);
    public static final Color BLACK = Color.valueOf(0x000000);
    
    public static final Color GRAY = Color.valueOf(0x808080);
    public static final Color LIGHT_GRAY = Color.valueOf(0xeeeeee);
    
    private final int value;
    
    private Color(int rgb){
        this.value = rgb;
    }
    
    public int getValue(){
        return value;
    }
    
    public int getRGB(){
        return value & 0x00ffffff;
    }
    
    public int getAlpha(){
        return (value >>> 24) & 0xff;
    }
    
    public int getRed(){
        return (value >>> 16) & 0xff;
    }
    
    public int getGreen(){
        return (value >>> 8) & 0xff;
    }
    
    public int getBlue(){
        return value & 0xff;
    }
    
    public float getOpacity(){
        return (float) (1 - (getAlpha() / 255.0));
    }
    
    public static Color valueOf(int value){
        return new Color(value & 0xffffff);
    }
    
    public static Color valueOf(int value, boolean hasAlpha){
        if (hasAlpha){
            return new Color(value); 
        }
        return valueOf(value);
    }
    
    public static Color valueOf(int red, int green, int blue){
        return new Color(
                ((red & 0xff) << 16) | 
                ((green & 0xff) << 8) | 
                ((blue & 0xff)));
    }
    
    public static Color valueOf(int alpha, int red, int green, int blue){
        return new Color(
                ((alpha & 0xff) << 24) | 
                ((red & 0xff) << 16) | 
                ((green & 0xff) << 8) | 
                ((blue & 0xff)));
    }
    
    public static String toString(int colorValue){
        StringBuilder value = new StringBuilder(7);
        value.append('#');
        int item;
        char chr;
        
        if ((colorValue >>> 24) != 0){
            // prints alpha
            
            item = (colorValue >>> 28) & 0xf;
            chr = (char) (item > 9 ? 'A' + (item-10) : '0' + item);
            value.append(chr);

            item = (colorValue >>> 24) & 0xf;
            chr = (char) (item > 9 ? 'A' + (item-10) : '0' + item);
            value.append(chr);
        }
        
        item = (colorValue >>> 20) & 0xf;
        chr = (char) (item > 9 ? 'A' + (item-10) : '0' + item);
        value.append(chr);
        
        item = (colorValue >>> 16) & 0xf;
        chr = (char) (item > 9 ? 'A' + (item-10) : '0' + item);
        value.append(chr);

        item = (colorValue >>> 12) & 0xf;
        chr = (char) (item > 9 ? 'A' + (item-10) : '0' + item);
        value.append(chr);

        item = (colorValue >>> 8) & 0xf;
        chr = (char) (item > 9 ? 'A' + (item-10) : '0' + item);
        value.append(chr);

        item = (colorValue >>> 4) & 0xf;
        chr = (char) (item > 9 ? 'A' + (item-10) : '0' + item);
        value.append(chr);
        
        item = colorValue & 0xf;
        chr = (char) (item > 9 ? 'A' + (item-10) : '0' + item);
        value.append(chr);

        return value.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this){
            return true;
        }
        if (obj instanceof Color){
            return ((Color)obj).value == this.value;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return value;
    }

    @Override
    public String toString() {
        return toString(value);
    }
    
}
